package com.tunnel.client;

import cn.hutool.json.JSONUtil;


import com.tunnel.client.hendler.ClientTunnelHandler;


import com.tunnel.common.config.ClientParsConfig;
import com.tunnel.common.config.client.ClientConfig;
import com.tunnel.common.protocol.DecodeHandler;
import com.tunnel.common.protocol.EncoderHandler;
import com.tunnel.common.protocol.Protocol;
import com.tunnel.common.protocol.ProtocolType;
import com.tunnel.common.util.SequenceUtil;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;

public class ClientApp {


    public void startApplication() throws InterruptedException {

        // 创建事件循环组
        EventLoopGroup group = new NioEventLoopGroup();
        Bootstrap bootstrap = new Bootstrap()
                .group(group)
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        //得到pipeline
                        ChannelPipeline pipeline = ch.pipeline();
                        // 加入自定义解码和编码
                        pipeline.addLast(new DecodeHandler());
                        pipeline.addLast(new EncoderHandler());
                        pipeline.addLast(new ClientTunnelHandler());
                    }
                });
        // 绑定端口数据
        ChannelFuture channelFuture = bootstrap.connect(ClientParsConfig.ClientConfig.getRemoteIp(), ClientParsConfig.ClientConfig.getRemotePort()).sync();
        // 直接注册一个监听器来监听回调的结果
        channelFuture.addListener((ChannelFutureListener) future -> {
            if (future.isSuccess()) {
                System.out.println("连接成功");
                registerClient(channelFuture.channel());
            } else {
                System.out.println("连接失败");
                // 暂停三秒钟，重新连接
                Thread.sleep(3000);
                startApplication();
            }
        });
        Channel channel = channelFuture.channel();
    }

    /**
     * 注册客户端到服务端上
     *
     * @param channel
     */
    private void registerClient(Channel channel) {
        Protocol protocol = new Protocol();
        protocol.setCommonType(ProtocolType.REGISTER);
        // 序列码
        Long sequenceId = SequenceUtil.getSequenceId();
        protocol.setSequenceId(sequenceId);
        String body = JSONUtil.parse(ClientParsConfig.ClientConfig).toString();
        protocol.setBody(body);
        protocol.setLength(body.getBytes().length);
        channel.writeAndFlush(protocol);
    }


}
